
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define MAXLINE 1024

static pthread_key_t    rl_key;
static pthread_once_t   rl_once = PTHREAD_ONCE_INIT;

static void readline_destructor(void * ptr) {

    free(ptr);
}

static void readline_once(void) {

    pthread_key_create(&rl_key, readline_destructor);
}

typedef struct {

    int     rl_cnt;
    char    *rl_buffer_ptr;
    char    *rl_buffer[MAXLINE];

}Rline;

static ssize_t my_read(Rline * tsd, int fd, char * ptr) {

    if (tsd->rl_cnt <= 0) {

        again:
        if ((tsd->rl_cnt = read(fd, tsd->rl_buffer, MAXLINE)) < 0) {

            if (errno == EINTR) {

                goto again;
            }
            return(-1);
        }
        else if (tsd->rl_cnt == 0) {

            return (0);
        }
        tsd->rl_buffer_ptr = tsd->rl_buffer;
    }
    tsd->rl_cnt--;
    *ptr = *tsd->rl_buffer_ptr++;
    return(1);
}

ssize_t readline(int fd, void * vptr, size_t maxlen) {


    size_t  n, rc;
    char    c, *ptr;
    Rline   *tsd;

    pthread_once(&rl_once, readline_once);

    if ((tsd = pthread_getspecific(rl_key)) == NULL) {

        tsd = calloc(1, sizeof(Rline));
        pthread_setspecific(rl_key, tsd);
    
    }
    ptr = vptr;
    for (n = 1; n < maxlen; n++) {

        if ((rc = my_read(tsd, fd, &c)) == 1) {

            *ptr++ = c;
            if (c == '\n') {

                break;
            }
            else if (rc == 0) {

                *ptr = 0;
                return (n -1);
            }
            else {

                return (-1);
            }
        }
    }
    *ptr = 0;
    return (n);
}

int main(int argc, char * argv[]) {


    return EXIT_SUCCESS;
}


